namespace tt{
namespace io{

//////////////////////////////////////////////////////////////////////////
template<>
inline
typename PathTraits<StringA>::CharType PathTraits<StringA>::GetSeparatorChar()
{
	return '/';
}

template<>
inline
typename PathTraits<StringA>::CharType PathTraits<StringA>::GetSeparatorCharWrong()
{
	return '\\';
}

template<>
inline
typename const PathTraits<StringA>::CharType* PathTraits<StringA>::GetSeparator()
{
	return "/";
}

//////////////////////////////////////////////////////////////////////////
template<>
inline
typename PathTraits<StringW>::CharType PathTraits<StringW>::GetSeparatorChar()
{
	return L'/';
}

template<>
inline
typename PathTraits<StringW>::CharType PathTraits<StringW>::GetSeparatorCharWrong()
{
	return L'\\';
}

template<>
inline
typename const PathTraits<StringW>::CharType* PathTraits<StringW>::GetSeparator()
{
	return L"/";
}

//////////////////////////////////////////////////////////////////////////
template<typename StringType>
PathBase<StringType>::PathBase()
: m_value()
{

}

template<typename StringType>
PathBase<StringType>::PathBase( const ValueType& value )
: m_value(value)
{
	Normalize();
}

template<typename StringType>
PathBase<StringType>::PathBase( const ValueType& value, const PathBaseNoNormalize& )
: m_value(value)
{
}

template<typename StringType>
PathBase<StringType>::PathBase( const PathBase& other )
: m_value(other.m_value)
{

}

template<typename StringType>
PathBase<StringType>& PathBase<StringType>::operator=( const PathBase& other )
{
	m_value = other.m_value;
	return *this;
}

template<typename StringType>
PathBase<StringType> PathBase<StringType>::operator/( const PathBase& other )
{
	PathBase<StringType> result(*this);
	if (!result.Empty())
	{
		result.m_value += PathTraits<StringType>().GetSeparator();
	}
	result.m_value += other.m_value;
	return result;
}

template<typename StringType>
PathBase<StringType> PathBase<StringType>::operator/( const ValueType& value )
{
	PathBase<StringType> result(*this);
	if (!result.Empty())
	{
		result.m_value += PathTraits<StringType>().GetSeparator();
	}
	result.m_value += value;
	result.Normalize();
	return result;
}

template<typename StringType>
Bool PathBase<StringType>::Empty() const
{
	return m_value.empty();
}

template<typename StringType>
const StringType& PathBase<StringType>::GetString() const
{
	return m_value;
}

template<typename StringType>
PathBase<StringType> PathBase<StringType>::GetParentPath() const
{
	if(Empty())
		return PathBase();

	for (Size index = m_value.length(); index != 0; --index)
	{
		const PathTraits<StringType>::CharType ch = m_value[index - 1];
		if (ch == PathTraits<StringType>().GetSeparatorChar())
		{
			StringType str(m_value.begin(), m_value.begin() + index - 1);
			PathBase path(str, PathBaseNoNormalize());
			return path;
		}
	}
	return PathBase();
}

//////////////////////////////////////////////////////////////////////////
template<typename StringType>
void PathBase<StringType>::Normalize()
{
	for (typename StringType::iterator it = m_value.begin(); it != m_value.end(); ++it)
	{
		if (*it == PathTraits<StringType>().GetSeparatorCharWrong())
			*it = PathTraits<StringType>().GetSeparatorChar();
	}
}

} //namespace io
} //namespace tt
